package com.xiyuan.smartutils;

import com.xiyuan.smartutils.constants.EnumConstants;
import com.xiyuan.smartutils.constants.SignConstants;
import com.xiyuan.smartutils.domain.date.DateRange;

import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoField;
import java.util.*;
import java.util.regex.Pattern;

/**
 * 基础日期工具类，包括功能如下：<br><br>
 * 1、日历和时间字符串转换<br>
 * 2、日历Long和时间字符串转换<br>
 * 3、日期Date和时间字符串转换<br>
 * 4、年月向上下取值，月最大天数<br>
 * 5、比较两个日期相差值<br>
 *
 * @version v1.0.0 @author lgz 2017-8-27 新建与整理
 */

@SuppressWarnings("all")
public final class DateTimes implements EnumConstants, SignConstants {
    
    private static final String FMT_YYYY_MM_DD = "(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})[-/](((0[13578]|1[02])[-/](0[1-9]|[12][0-9]|3[01]))|((0[469]|11)[-/](0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29)";
    public static final Pattern DATE_ = Pattern.compile("^" + FMT_YYYY_MM_DD + "$");
    public static final Pattern DATE_HH = Pattern.compile("^" + FMT_YYYY_MM_DD + " 0[0-9]$");
    public static final Pattern DATE_HH_MM = Pattern.compile("^" + FMT_YYYY_MM_DD + " 0[0-9]:0[0-9]$");
    public static final Pattern DATE_HH_MM_SS = Pattern.compile("^" + FMT_YYYY_MM_DD + " 0[0-9]:0[0-9]:0[0-9]$");
    private static final ZoneId DEF_ZONE = ZoneId.systemDefault();
    
    private DateTimes() {}
    /************************************************************************/
    // 日期常量定义，用得比较多的几个定义成常量
    /************************************************************************/
    
    /**
     * format code yyyy-MM-dd
     */
    public static final String YYYY_MM_DD = "yyyy-MM-dd";
    
    /**
     * format code HH:mm:ss
     */
    public static final String HH_MM_SS = "HH:mm:ss";
    
    /**
     * format code yyyy-MM-dd HH:mm:ss
     */
    public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
    
    public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
    public static final String MMDDHHMMSS = "MMddHHmmss";
    public static final String MMDDHHMM = "MMddHHmm";
    public static final String MMDD = "MMdd";
    
    
    private static Map<String, DateTimeFormatter> formatterMap = new HashMap<>();
    
    
    public static DateTimeFormatter getFormatter(String format) {
        return formatterMap.computeIfAbsent(format, k -> DateTimeFormatter.ofPattern(format).withZone(DEF_ZONE));
    }
    
    /**
     * yyyy-MM-dd HH:mm:ss,SSS
     */
    public static final DateTimeFormatter DTF_YYYY_MM_DD_HH_MM_SS_SSS = getFormatter("yyyy-MM-dd HH:mm:ss,SSS");
    public static final DateTimeFormatter DTF_YYYY_MM_DD_HH_MM_SS = getFormatter(YYYY_MM_DD_HH_MM_SS);
    public static final DateTimeFormatter DTF_YYYY_MM_DD = getFormatter(YYYY_MM_DD);
    public static final DateTimeFormatter DTF_YYYYMMDDHHMMSS = getFormatter(YYYYMMDDHHMMSS);
    public static final DateTimeFormatter DTF_MMDDHHMMSS = getFormatter(MMDDHHMMSS);
    public static final DateTimeFormatter DTF_MMDDHHMM = getFormatter(MMDDHHMM);
    public static final DateTimeFormatter DTF_MMDD = getFormatter(MMDD);
    public static final DateTimeFormatter DTF_HH_MM_SS = getFormatter(HH_MM_SS);
    
    
    private static final DateTimeFormatter MULTI_FORMATTER = new DateTimeFormatterBuilder()
            
            // "20250806223511+0800"
            .optionalStart()
            .appendPattern("yyyyMMddHHmmss")  // 日期部分
            .optionalEnd()
            
            // "20250806223511000+0800"
            .optionalStart()
            .appendPattern("yyyyMMddHHmmss")  // 日期部分
            .appendValue(ChronoField.MILLI_OF_SECOND, 3)  // 毫秒
            .optionalStart().appendPattern("[Z][XX][XXX]").optionalEnd()
            .optionalEnd()
            
            // 通用格式通用格式化器
            .optionalStart()
            .appendPattern("[yyyy[[-][/][年]]M[-][/][月]d[日]][yyyyMMdd][yyyyMM]") //
            .optionalStart().appendLiteral(' ').optionalEnd()
            // 时间部分（支持三种格式）
            .appendPattern("[['T']]")
            .appendPattern("[HH][[:][时]][mm][[:][分]][ss[秒]]")
            .appendPattern("[[.][,]][SSS[毫秒]]")
            
            // 时区偏移量（+0800 或 +08:00）
            .optionalStart().appendLiteral(' ').optionalEnd()
            .optionalEnd()
            
            // 公共部分
            .appendPattern("[Z][XX][XXX]")
            .parseDefaulting(ChronoField.MONTH_OF_YEAR, 1)
            .parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
            .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
            .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
            .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
            .parseDefaulting(ChronoField.NANO_OF_SECOND, 0)
            .toFormatter().withZone(ZoneId.systemDefault());
    ;
    /************************************************************************/
    // 日历转换，String和Calendar之间转换
    
    /************************************************************************/
    public static DateTimeFormatter getComplexParser() {
        
        return MULTI_FORMATTER;
    }
    
    /**
     * 解析字符串时间格式
     *
     * @param dateText
     * @return
     */
    public static Date parse(String dateText) {
        return StrUtils.isBlank(dateText) ? null : Date.from(Instant.from(MULTI_FORMATTER.parse(dateText)));
    }
    
    /**
     * 格式化时间
     *
     * @param date
     * @param format 时间格式 默认为 yyyy-MM-dd HH:mm:ss 格式
     * @return
     */
    public static String format(Date date, String format) {
        if (date == null) {
            return null;
        }
        Instant _date = date.toInstant();
        return StrUtils.isBlank(format) ? DTF_YYYY_MM_DD_HH_MM_SS.format(_date) : getFormatter(format).format(_date);
    }
    
    /**
     * 返回当前时间的Date
     */
    public static Date nowDate() {
        return new Date();
    }
    
    /**
     * 字符串转为日历
     *
     * @param datetime 标准时间格式 "yyyy-MM-dd HH:mm:ss" 或者 "yyyy-MM-dd"
     * @return Calendar
     */
    public static Calendar toCalendar(String datetime) {
        if (datetime == null) return null;
        
        int index = datetime.indexOf(_SPACE_);
        String date = index == -1 ? datetime : datetime.substring(0, index);
        String time = index == -1 ? "00:00:00" : datetime.substring(index + 1);
        try {
            return toCalendar(date, time);
        }
        catch (RuntimeException e) {
            if (Validates.isInteger(datetime) && datetime.length() > 10 && datetime.length() < 16) {
                // long 类型
                Calendar calendar = Calendar.getInstance();
                calendar.setTimeInMillis(Long.parseLong(datetime));
                return calendar;
            }
            
            try {
                // 只有 时分秒
                int[] ts = parseTime(datetime);
                Calendar c = Calendar.getInstance();
                // c.set(Calendar.YEAR, year);
                // c.set(Calendar.MONTH, month - 1);
                // c.set(Calendar.DATE, day < 0 ? 0 : day > 31 ? 31 : day);
                int HH = ts[0];
                int mm = ts[1];
                int ss = ts[2];
                int ff = ts[3];
                c.set(Calendar.HOUR_OF_DAY, HH < 0 ? 0 : HH > 23 ? 23 : HH);
                c.set(Calendar.MINUTE, mm < 0 ? 0 : mm > 59 ? 59 : mm);
                c.set(Calendar.SECOND, ss < 0 ? 0 : ss > 59 ? 59 : ss);
                c.set(Calendar.MILLISECOND, ff < 0 ? 0 : ff > 999 ? 0 : ff);
                return c;
            }
            catch (Exception ex) {
            }
            
            throw e;
        }
    }
    
    /**
     * 时分秒转换
     *
     * @param time
     * @return int[] [时,分,秒,毫秒]
     */
    public static int[] parseTime(String time) {
        int[] ts = new int[4];
        String[] tsr = StrUtils.trimToEmpty(time).split(_COLON_ + "");
        for (int i = 0; i < tsr.length; i++) {
            tsr[i] = StrUtils.trimToNull(tsr[i]);
        }
        try {
            if (tsr.length >= 1 && tsr[0] != null) ts[0] = Integer.parseInt(tsr[0]);
            if (tsr.length >= 2 && tsr[1] != null) ts[1] = Integer.parseInt(tsr[1]);
            String mis = tsr.length >= 3 && tsr[2] != null ? tsr[2] : null;
            if (mis != null) {
                mis = mis.replace(",", ".");
                int mi = (int) (Double.parseDouble(mis) * 1000);
                ts[2] = mi / 1000;
                ts[3] = mi % 1000;
            }
            return ts;
        }
        catch (Exception e) {
            throw new IllegalArgumentException("非法的参数time[" + time + "]");
        }
        
    }
    
    /**
     * 字符串转为日历,字符串符合标准日期格式yyyy-MM-dd,和标准时间格式HH:mm:ss
     *
     * @param date 标准日期格式yyyy-MM-dd 或者 "yyyy-MM-dd"
     * @param time 标准时间格式HH:mm:ss
     * @return Calendar
     */
    public static Calendar toCalendar(String date, String time) {
        Asserts.nonBlank(date, "date");
        
        String[] ds = date.split("[/-]");
        Asserts.as(ds.length == 3 ? null : "非法的参数date[" + date + "]");
        
        int tmp = 0;
        int[] ts = parseTime(time);
        int yy = Integer.parseInt(ds[0]);
        int MM = Integer.parseInt(ds[1]);
        int dd = Integer.parseInt(ds[2]);
        
        // dd/mm/yyyy
        if (dd > yy) {
            tmp = yy;
            yy = dd;
            dd = tmp;
            tmp = 0;
        }
        
        if (MM > 12 && MM > dd) {
            tmp = MM;
            MM = dd;
            dd = tmp;
            tmp = 0;
        }
        Asserts.as(yy > 1000 ? null : "非法的参数date[" + date + "]");
        Asserts.as(MM > 0 && MM <= 12 ? null : "非法的参数date[" + date + "]");
        Asserts.as(dd > 0 && dd <= 31 ? null : "非法的参数date[" + date + "]");
        
        int H2 = ts[0];
        int m2 = ts[1];
        int s2 = ts[2];
        int f3 = ts[3];
        
        return toCalendar(yy, MM, dd, H2, m2, s2, f3);
    }
    
    /**
     * 通过标准时间输入,年,月,日,时,分,秒,生成Calendar，默认毫秒为0
     *
     * @param year  年
     * @param month 月
     * @param day   日
     * @param time  时间
     * @return Calendar
     */
    public static Calendar toCalendar(String year, String month, String day, String time) {
        
        int[] ts = parseTime(time);
        int y4 = Integer.parseInt(year);
        int M2 = Integer.parseInt(month);
        int d2 = Integer.parseInt(day);
        int H2 = ts[0];
        int m2 = ts[1];
        int s2 = ts[2];
        int f3 = ts[3];
        Asserts.as(y4 > 1000 ? null : "非法的参数year[" + year + "]");
        Asserts.as(M2 > 0 && M2 < 12 ? null : "非法的参数month[" + month + "]");
        Asserts.as(d2 > 0 && d2 < 31 ? null : "非法的参数day[" + day + "]");
        return toCalendar(y4, m2, d2, H2, m2, s2, f3);
        
    }
    
    /**
     * 通过标准时间输入,年,月,日,时,分,秒,生成Calendar，默认毫秒为0
     *
     * @param year   年
     * @param month  月， 值范围：1-12
     * @param day    日
     * @param hour   时
     * @param minute 分
     * @param second 秒
     * @return Calendar
     */
    public static Calendar toCalendar(String year,
                                      String month,
                                      String day,
                                      String hour,
                                      String minute,
                                      String second) {
        int y4 = Integer.parseInt(year);
        int M2 = Integer.parseInt(month);
        int d2 = Integer.parseInt(day);
        int H2 = Integer.parseInt(hour);
        int m2 = Integer.parseInt(minute);
        int s2 = Integer.parseInt(second);
        Asserts.as(y4 > 1000 ? null : "非法的参数year[" + year + "]");
        Asserts.as(M2 > 0 && M2 < 12 ? null : "非法的参数month[" + month + "]");
        Asserts.as(d2 > 0 && d2 < 31 ? null : "非法的参数day[" + day + "]");
        return toCalendar(y4, M2, d2, H2, m2, s2);
    }
    
    public static Calendar toCalendar(String year,
                                      String month,
                                      String day,
                                      String hour,
                                      String minute,
                                      String second,
                                      String millisecond) {
        int y4 = Integer.parseInt(year);
        int M2 = Integer.parseInt(month);
        int d2 = Integer.parseInt(day);
        int H2 = Integer.parseInt(hour);
        int m2 = Integer.parseInt(minute);
        int s2 = Integer.parseInt(second);
        int f3 = Integer.parseInt(millisecond);
        Asserts.as(y4 > 1000 ? null : "非法的参数year[" + year + "]");
        Asserts.as(M2 > 0 && M2 < 12 ? null : "非法的参数month[" + month + "]");
        Asserts.as(d2 > 0 && d2 < 31 ? null : "非法的参数day[" + day + "]");
        return toCalendar(y4, M2, d2, H2, m2, s2, f3);
    }
    
    /**
     * 通过标准时间输入,年,月,日,时,分,秒,生成Calendar，默认毫秒为0
     *
     * @param year   年
     * @param month  月， 值范围：1-12
     * @param day    日
     * @param hour   时
     * @param minute 分
     * @param second 秒
     * @return Calendar
     */
    public static Calendar toCalendar(int year, int month, int day, int hour, int minute, int second) {
        return toCalendar(year, month, day, hour, minute, second, 0);
    }
    
    public static Calendar toCalendar(int year, int month, int day, int hour, int minute, int second, int millisecond) {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.YEAR, year);
        c.set(Calendar.MONTH, month - 1);
        c.set(Calendar.DATE, day < 0 ? 0 : day > 31 ? 31 : day);
        c.set(Calendar.HOUR_OF_DAY, hour < 0 ? 0 : hour > 23 ? 23 : hour);
        c.set(Calendar.MINUTE, minute < 0 ? 0 : minute > 59 ? 59 : minute);
        c.set(Calendar.SECOND, second < 0 ? 0 : second > 59 ? 59 : second);
        c.set(Calendar.MILLISECOND, millisecond < 0 ? 0 : millisecond > 999 ? 0 : millisecond);
        
        return c;
    }
    
    /**
     * HTTP时间格式转化为日历时间格式
     *
     * @param datetime HTTP时间格式"Wed, 31 Dec 2014 04:06:10 GMT"对应为北京时间 2014-12-31 12:06:10
     * @return Calendar
     */
    public static Calendar toCalendarHttp(String datetime) {
        Asserts.as(Validates.isLen(datetime, 29, 29) ? null : "参数[" + datetime + "]不是HTTP GMT标准格式");
        
        String week = datetime.substring(0, 3);
        Asserts.as(Validates.isContain(_WEEKS_, week) ? null : "参数[" + datetime + "]不是HTTP GMT标准格式");
        
        char comma = datetime.charAt(3);
        Asserts.as(comma == _COMMA_ ? null : "参数[" + datetime + "]不是HTTP GMT标准格式");
        
        char space = datetime.charAt(4);
        Asserts.as(space == _SPACE_ ? null : "参数[" + datetime + "]不是HTTP GMT标准格式");
        
        String day = datetime.substring(5, 7);
        Asserts.as(Validates.isDay(day) ? null : "参数[" + datetime + "]不是HTTP GMT标准格式");
        
        space = datetime.charAt(7);
        Asserts.as(space == _SPACE_ ? null : "参数[" + datetime + "]不是HTTP GMT标准格式");
        
        String month = datetime.substring(8, 11);
        Asserts.as(Validates.isContain(_MONTHS_, month) ? null : "参数[" + datetime + "]不是HTTP GMT标准格式");
        
        space = datetime.charAt(11);
        Asserts.as(space == _SPACE_ ? null : "参数[" + datetime + "]不是HTTP GMT标准格式");
        
        String year = datetime.substring(12, 16);
        Asserts.as(Validates.isYear(year) ? null : "参数[" + datetime + "]不是HTTP GMT标准格式");
        
        space = datetime.charAt(16);
        Asserts.as(space == _SPACE_ ? null : "参数[" + datetime + "]不是HTTP GMT标准格式");
        
        String time = datetime.substring(17, 25);
        Asserts.as(Validates.isTime(time) ? null : "参数[" + datetime + "]不是HTTP GMT标准格式");
        
        space = datetime.charAt(25);
        Asserts.as(space == _SPACE_ ? null : "参数[" + datetime + "]不是HTTP GMT标准格式");
        
        String gmt = datetime.substring(26);
        Asserts.as("GMT".equals(gmt) ? null : "参数[" + datetime + "]不是HTTP GMT标准格式");
        
        int m = Arrays.indexOf(_MONTHS_, month) + 1;
        Calendar calendar = toCalendar(year, StrUtils.prefixZero(m, 2), day, time);
        calendar.setTimeZone(new SimpleTimeZone(0, "GMT"));
        
        return calendar;
    }
    
    /**
     * 日历转字符串，给定格式的日期时间字符串
     *
     * @param calendar 日历,给定一个日历
     * @param format   格式,如yyyy-MM-dd HH:mm:ss
     * @return 取得给定日历, 给定格式的日期时间字符串
     */
    public static String toDateTimeString(Calendar calendar, String format) {
        return getFormatter(format).format(calendar.toInstant());
    }
    
    /**
     * 日历转标准时间字符串
     *
     * @param calendar 日历,给定一个日历
     * @return 取得默认的日期时间字符串yyyy-MM-dd HH:mm:ss
     */
    public static String toDateTimeString(Calendar calendar) {
        return DTF_YYYY_MM_DD_HH_MM_SS.format(calendar.toInstant());
    }
    
    /**
     * 日历转标准日期字符串
     *
     * @param calendar 日历,给定一个日历
     * @return String 取得默认的日期时间字符串yyyy-MM-dd
     */
    public static String toDateString(Calendar calendar) {
        return DTF_YYYY_MM_DD.format(calendar.toInstant());
    }
    
    /**
     * HTTP格式时间转标准时间字符串
     *
     * @param datetime HTTP时间格式Wed, 31 Dec 2014 04:06:10 GMT对应为北京时间 2014-12-31 12:06:10
     * @return 取得默认的日期时间字符串yyyy-MM-dd HH:mm:ss
     */
    public static String toDateTimeStringHttp(String datetime) {
        Calendar calendar = toCalendarHttp(datetime);
        return toDateTimeString(calendar);
    }
    
    /********************************************************/
    // 时间值转换，String和long之间转换
    /********************************************************/
    
    /**
     * 取得给定时间,给定格式的日期时间字符串,标准格式:yyyy-MM-dd HH:mm:ss
     *
     * @param datetime 日期,给定一个时间的毫秒数
     * @return 取得给定时间, 给定格式的日期时间字符串
     */
    public static String toDateTimeString(long datetime) {
        return DTF_YYYY_MM_DD_HH_MM_SS.format(new Date(datetime).toInstant());
    }
    
    /**
     * 取得给定时间,给定格式的日期时间字符串,标准格式:"yyyy-MM-dd HH:mm:ss,SSS";
     *
     * @param datetime 日期,给定一个时间的毫秒数
     * @return String 取得给定时间,给定格式的日期时间字符串
     */
    public static String toDateTimeSSSString(long datetime) {
        return DTF_YYYY_MM_DD_HH_MM_SS_SSS.format(new Date(datetime).toInstant());
    }
    
    /**
     * 取得给定时间,给定格式的日期时间字符串
     *
     * @param datetime 日期,给定一个时间的毫秒数
     * @param format   格式,如yyyy-MM-dd HH:mm:ss
     * @return 取得给定时间, 给定格式的日期时间字符串
     */
    public static String toDateTimeString(long datetime, String format) {
        return getFormatter(format).format(new Date(datetime).toInstant());
    }
    
    /**
     * 通过标准时间输入,年,月,日,时,分,秒,生成long值
     *
     * @param year   年
     * @param month  月
     * @param day    日
     * @param hour   时
     * @param minute 分
     * @param second 秒
     * @return long
     */
    public static long toLong(int year, int month, int day, int hour, int minute, int second) {
        return toCalendar(year, month, day, hour, minute, second).getTimeInMillis();
    }
    
    /**
     * 通过标准时间输入,年,月,日,时,分,秒,生成long值
     *
     * @param year   年
     * @param month  月
     * @param day    日
     * @param hour   时
     * @param minute 分
     * @param second 秒
     * @return long
     */
    public static long toLong(String year, String month, String day, String hour, String minute, String second) {
        return toCalendar(year, month, day, hour, minute, second).getTimeInMillis();
    }
    
    /**
     * 字符串转为Long时间
     *
     * @param datetime 标准日期格式yyyy-MM-dd HH:mm:ss
     * @return Long时间
     */
    public static long toLong(String datetime) {
        return toCalendar(datetime).getTimeInMillis();
    }
    
    /**
     * 字符串转为时间,字符串符合标准日期格式:yyyy-MM-dd,和标准时间格式:HH:mm:ss
     *
     * @param date 标准日期格式yyyy-MM-dd
     * @param time 标准时间格式HH:mm:ss
     * @return Long时间
     */
    public static long toLong(String date, String time) {
        return toCalendar(date, time).getTimeInMillis();
    }
    
    /**
     * HTTP时间格式转化为长整型时间格式
     *
     * @param httpDate HTTP时间格式Wed, 31 Dec 2014 04:06:10 GMT对应为北京时间2014-12-31 12:06:10
     * @return Long时间
     */
    public static long toLongHttp(String httpDate) {
        Calendar calendar = toCalendarHttp(httpDate);
        return calendar.getTimeInMillis();
    }
    
    /**
     * 时间段重叠
     *
     * @param range1 第一个时间段
     * @param range2 第二个时间段
     * @return 返回重叠时间段， 如果不存在重叠则返回 null
     */
    public static DateRange getOverlapRange(DateRange range1, DateRange range2) {
        if (range1 == null || range2 == null) {
            Asserts.as("日期时间段不能为空！");
        }
        if (!range1.isRange()) {
            Asserts.as(" 无效日期时间段：" + range1);
        }
        if (!range2.isRange()) {
            Asserts.as(" 无效日期时间段：" + range2);
        }
        
        long s1 = range1.getStartTime(), e1 = range1.getEndTime();
        long s2 = range2.getStartTime(), e2 = range2.getEndTime();
        Date min = s1 >= s2 ? range1.getStart() : range2.getStart();
        Date max = e1 <= e2 ? range1.getEnd() : range2.getEnd();
        return max.getTime() >= min.getTime() ? new DateRange(min, max) : null;
    }
    
    /********************************************************/
    // 时间转换，String和Date之间转换
    /********************************************************/
    /**
     * 生成标准日期，格式为yyyy-MM-dd
     *
     * @param date 日期对象
     * @return 日期字符串，格式为yyyy-MM-dd
     */
    public static String toDateString(Date date) {
        return date == null ? null : DTF_YYYY_MM_DD.format(date.toInstant());
    }
    
    /**
     * 生成年月的日期，格式为MMdd
     *
     * @param yearDay 当年日期值（1-366）之间
     * @return 日期字符串，格式为MMdd
     */
    public static String toDateString(int yearDay) {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.DAY_OF_YEAR, yearDay);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        
        return toDateTimeString(c, MMDD);
    }
    
    /**
     * 生成指定格式字符串，如格式为yyyy-MM-dd
     *
     * @param date   日期对象
     * @param format 格式如yyyy-MM-dd
     * @return 日期字符串
     */
    public static String toDateTimeString(Date date, String format) {
        return date == null ? null : getFormatter(format).format(date.toInstant());
    }
    
    /**
     * 生成标准格式的字符串 格式为yyyy-MM-dd HH:mm:ss
     *
     * @param date 日期对象
     * @return 生成默认格式的字符串 格式为yyyy-MM-dd HH:mm:ss
     */
    public static String toDateTime(Date date) {
        return date == null ? null : DTF_YYYY_MM_DD_HH_MM_SS.format(date.toInstant());
    }
    
    /**
     * 生成标准格式的字符串 格式为yyyy-MM-dd HH:mm:ss
     *
     * @param date 日期对象
     * @return 生成默认格式的字符串 格式为yyyy-MM-dd HH:mm:ss
     */
    public static String toDateTimeString(Date date) {
        return date == null ? null : DTF_YYYY_MM_DD_HH_MM_SS.format(date.toInstant());
    }
    
    /**
     * 字符串转为时间
     *
     * @param datetime 标准时间格式yyyy-MM-dd HH:mm:ss 或者 yyyy-MM-dd
     * @return 日期对象
     */
    public static Date toDate(String datetime) {
        return datetime == null ? null : toCalendar(datetime).getTime();
    }
    
    /**
     * 字符串转为时间,字符串符合标准日期格式yyyy-MM-dd，和标准时间格式:HH:mm:ss
     *
     * @param date 标准日期格式yyyy-MM-dd
     * @param time 标准时间格式HH:mm:ss
     * @return 日期对象
     */
    public static Date toDate(String date, String time) {
        return toCalendar(date, time).getTime();
    }
    
    /**
     * 通过标准时间输入,年,月,日,时,分,秒,生成Date,毫秒位为000
     *
     * @param year   年
     * @param month  月
     * @param day    日
     * @param hour   时
     * @param minute 分
     * @param second 秒
     * @return 日期对象
     */
    public static Date toDate(String year, String month, String day, String hour, String minute, String second) {
        return toCalendar(year, month, day, hour, minute, second).getTime();
    }
    
    /**
     * 通过标准时间输入,年,月,日,时,分,秒,生成Date,毫秒位为000
     *
     * @param year   年
     * @param month  月
     * @param day    日
     * @param hour   时
     * @param minute 分
     * @param second 秒
     * @return Date对象
     */
    public static Date toDate(int year, int month, int day, int hour, int minute, int second) {
        return toCalendar(year, month, day, hour, minute, second).getTime();
    }
    
    
    /**
     * 字符串转为时间 自动识别格式
     *
     * <pre>
     * 支持如下格式
     * "20230505 23:53:22"
     * "20230505 23:53:22.456"
     * "20230505 23:53:22,456"
     * "2023-05-05T23:53:22.456+0800"
     * "2023-05-05T235322456+0800"
     * "2023-05-05 T23:53:22.456+0800"
     * "2023-05-05 23:53:22.456+0800"
     * "2023-05-05 23:53:22.456+08:00"
     * "2023-05-05 23:53:22.456Z"
     * "2023/05/05 23:53:22,456Z"
     * "2023年05月05日 23时53分22秒,456毫秒 +0800"
     * "2023年05月05日23时53分22秒,456毫秒 +0800"
     * "2023年05月05日23时53分22秒456毫秒 +0800"
     * "2023年05月05日23时53分22秒456毫秒+0800"
     * "20230505 23:53:22.456+0800"
     * "20250806223511000+0600"
     * "20250806223511000+06:00"
     * "20250806223511000"
     * "20250806223511+0800"
     * "20250806223511+08:00"
     * "20250806223511+08:00"
     * "20250806 22:35"
     *
     * </pre>
     *
     * @return 日期对象
     */
    public static Date from(CharSequence str) throws DateTimeParseException {
        return str == null || StrUtils.isBlank(str) ? null : Date.from(Instant.from(MULTI_FORMATTER.parse(str)));
    }
    
    /**
     * 根据输入的时,分,秒,生成时间格式 HH:mm:ss
     *
     * @param hour   时
     * @param minute 分
     * @param second 秒
     * @return 生成时间格式为HH:mm:ss
     */
    public static String toTimeString(int hour, int minute, int second) {
        String h = String.valueOf(hour);
        String m = String.valueOf(minute);
        String s = String.valueOf(second);
        
        if (hour < 10) {h = "0" + hour;}
        
        if (minute < 10) {m = "0" + minute;}
        
        if (second < 10) {s = "0" + second;}
        
        return h + ":" + m + ":" + s;
    }
    
    /**
     * 根据输入的时间,生成时间格式 HH:mm:ss
     *
     * @param date Date对象
     * @return 生成时间格式为HH:mm:ss
     */
    public static String toTimeString(Date date) {
        return date == null ? null : DTF_HH_MM_SS.format(date.toInstant());
    }
    
    /**
     * 获取当前日期的转化，格式yyyy-MM-dd或yyyy/MM/dd，转为yyyyMMdd,
     *
     * @param date 日期字符串，yyyy-MM-dd或yyyy/MM/dd
     * @return 日期整型，yyyyMMdd
     */
    public static int toDateInt(String date) {
        // 去掉中间的符号
        StringBuilder strb = new StringBuilder();
        for (int i = 0; i < date.length(); i++) {
            if (strb.length() == 8) {
                break;
            }
            
            char c = date.charAt(i);
            if (Validates.isDigit(c)) {
                if ('0' < c && c <= '9' && (strb.length() == 4 || strb.length() == 6)) {
                    strb.append(0);
                }
                strb.append(c);
            }
        }
        
        // 转为整型
        return Integer.parseInt(strb.toString());
    }
    
    /********************************************************/
    // 相关的日期计算方法
    /********************************************************/
    
    /**
     * 获取指定月天数,格式：yyyyMM
     *
     * @param date 格式：yyyyMM
     * @return 2月28/29，1月31
     */
    public static int getMonthDays(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return getMonthDays(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH) + 1);
    }
    
    /**
     * 获取指定月天数,格式：yyyyMM
     *
     * @param yearMonth 格式：yyyyMM
     * @return 2月28/29，1月31
     */
    public static int getMonthDays(String yearMonth) {
        int year = Integer.parseInt(yearMonth.substring(0, 4));
        int month = Integer.parseInt(yearMonth.substring(4));
        return getMonthDays(year, month);
    }
    
    /**
     * 获取指定月天数
     *
     * @param yearMonth 年月份201305
     * @return 2月28/29，1月31
     */
    public static int getMonthDays(int yearMonth) {
        int year = yearMonth / 100;
        int month = yearMonth % 100;
        return getMonthDays(year, month);
    }
    
    /**
     * 获取指定月天数
     *
     * @param year  年份
     * @param month 月份
     * @return 2月28/29，1月31
     */
    public static int getMonthDays(int year, int month) {
        switch (month) {
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
                return 31;
            case 4:
            case 6:
            case 9:
            case 11:
                return 30;
            default:// 2月
                return Validates.isLeapYear(year) ? 29 : 28;
        }
    }
    
    /**
     * 获取指定年月的下一个年月，格式:yyyyMM
     *
     * @param yearMonth 指定的年月，格式:yyyyMM
     * @return yyyyMM
     */
    public static int getNextMonth(int yearMonth) {
        int year = yearMonth / 100;
        int month = yearMonth % 100;
        if (month < 12) {
            month += 1;
        }
        else {
            year += 1;
            month = 1;
        }
        
        return year * 100 + month;
    }
    
    /**
     * 获取指定年月的下一个月，格式:yyyyMM
     *
     * @param yearMonth 指定的年月，格式:yyyyMM
     * @return yyyyMM
     */
    public static String getNextMonth(String yearMonth) {
        int curYearMonth = Integer.parseInt(yearMonth);
        return String.valueOf(getNextMonth(curYearMonth));
    }
    
    /**
     * 获到下一个月份yyyy-MM, curYearMonth格式yyyyMM或yyyy-MM
     *
     * @param yearMonth 指定的年月，格式:yyyyMM或yyyy-MM
     * @return yyyy-MM
     */
    public static String getNextMonthSpe(String yearMonth) {
        yearMonth = yearMonth.replaceAll("-", _EMPTY_);
        String nextYearMonth = getNextMonth(yearMonth);
        return nextYearMonth.substring(0, 4) + "-" + nextYearMonth.substring(4);
    }
    
    /**
     * 获取下一日的值, yyyyMMdd
     *
     * @param date yyyyMMdd格式的int型值
     * @return yyyyMMdd格式的int型值
     */
    public static int getNextDay(int date) {
        int yearMonth = date / 100;
        int day = date % 100;
        
        int monthDays = getMonthDays(yearMonth);
        if (day < monthDays) {day += 1;}
        else {
            yearMonth = getNextMonth(yearMonth);
            day = 1;
        }
        return yearMonth * 100 + day;
    }
    
    /**
     * 获取下一小时的值, yyyyMMddHH
     *
     * @param curHour yyyyMMddHH格式的long型值
     * @return yyyyMMddHH格式的long型值
     */
    public static long getNextHour(long curHour) {
        long yearMonthDay = curHour / 100;
        long hour = curHour % 100;
        
        if (hour < 23) {hour += 1;}
        else {
            yearMonthDay = getNextDay((int) yearMonthDay);
            hour = 0;
        }
        
        return yearMonthDay * 100 + hour;
    }
    
    /**
     * 获取下一分钟的值, yyyyMMddHHmm
     *
     * @param curMinute yyyyMMddHHmm格式的long型值
     * @return yyyyMMddHHmm格式的long型值
     */
    public static long getNextMinute(long curMinute) {
        long yearMonthDayHour = curMinute / 100;
        long minute = curMinute % 100;
        
        if (minute < 59) {minute += 1;}
        else {
            yearMonthDayHour = getNextHour((int) yearMonthDayHour);
            minute = 0;
        }
        
        return yearMonthDayHour * 100 + minute;
    }
    
    /**
     * 获取指定年月的上一个年月，格式:yyyyMM
     *
     * @param yearMonth 指定的年月，格式:yyyyMM
     * @return yyyyMM
     */
    public static String getPreviousYearMonth(String yearMonth) {
        int year = Integer.parseInt(yearMonth.substring(0, 4));
        int month = Integer.parseInt(yearMonth.substring(4));
        if (month == 1) {
            year -= 1;
            month = 12;
        }
        else {
            month -= 1;
        }
        
        StringBuilder strb = new StringBuilder().append(year);
        if (month > 9) {strb.append(month);}
        else {strb.append("0").append(month);}
        return strb.toString();
    }
    
    /**
     * 获到上一个月份yyyy-MM, curYearMonth格式yyyyMM或yyyy-MM
     *
     * @param yearMonth 指定的年月，格式:yyyyMM或yyyy-MM
     * @return yyyy-MM
     */
    public static String getPreviousYearMonthSpe(String yearMonth) {
        yearMonth = yearMonth.replaceAll("-", _EMPTY_);
        String prevYearMonth = getPreviousYearMonth(yearMonth);
        return prevYearMonth.substring(0, 4) + "-" + prevYearMonth.substring(4);
    }
    
    /**
     * 获取指定日期格式为20170101得到20161231格式的前一天
     *
     * @param date 指定日期值
     * @return 前一天日期值
     */
    public static int getPreviousDateInt(int date) {
        int year = date / 10000;
        int month = date / 100 % 100;
        int day = date % 100;
        if (day == 1) {
            year = month == 1 ? year - 1 : year;
            month = month == 1 ? 12 : month - 1;
            day = DateTimes.getMonthDays(year, month);
        }
        else {
            day--;
        }
        
        return year * 10000 + month * 100 + day;
    }
    
    /**
     * 获到指定月最后一天yyyy-MM-dd
     *
     * @param yearMonth yyyyMM
     * @return 如2014-02-28,2014-01-31
     */
    public static String getLastMonthDay(String yearMonth) {
        String yearStr = yearMonth.substring(0, 4);
        String monthStr = yearMonth.substring(4);
        int year = Integer.parseInt(yearStr);
        int month = Integer.parseInt(monthStr);
        switch (month) {
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
                return yearStr + "-" + monthStr + "-31";
            case 4:
            case 6:
            case 9:
            case 11:
                return yearStr + "-" + monthStr + "-30";
            case 2:
                int day = Validates.isLeapYear(year) ? 29 : 28;
                return yearStr + "-" + monthStr + "-" + day;
        }
        
        throw Asserts.exception("请求参数[" + yearMonth + "]格式不对或数据不对");
    }
    
    /********************************************************/
    // 时间比较
    /********************************************************/
    
    /**
     * 获取两个日期对象相差年数，不管月日，如2014-02-19比2013-12-22年份差值为1
     *
     * @param date1 日期对象
     * @param date2 日期对象
     * @return int 年份差值
     */
    public static int compareYear(Date date1, Date date2) {
        Asserts.nonNull(date1, "date1");
        Asserts.nonNull(date2, "date2");
        
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date1);
        int year1 = calendar.get(Calendar.YEAR);
        
        calendar.setTime(date2);
        int year2 = calendar.get(Calendar.YEAR);
        
        return year1 - year2;
    }
    
    /**
     * 获取两个日期对象相差月数，年月一起比，如2014-02比2013-12差值为12*(2014-2013)+(2-12)=2，日期不处理
     *
     * @param date1 日期对象
     * @param date2 日期对象
     * @return int 月份差值
     */
    public static int compareMonth(Date date1, Date date2) {
        if (date1 == null || date2 == null) {return 0;}
        
        int year = compareYear(date1, date2);
        
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date1);
        int month1 = calendar.get(Calendar.MONTH);
        
        calendar.setTime(date2);
        int month2 = calendar.get(Calendar.MONTH);
        
        /* 进行比较 */
        return 12 * year + (month1 - month2);
        
    }
    
    /**
     * 获取两个日期对象相差月数,大一整月才算大一个月
     *
     * @param date1 字符串对象
     * @param date2 字符串对象
     * @return int 月份差值
     */
    public static int compareMonth(String date1, String date2) {
        if (date1 == null || date2 == null) {return 0;}
        
        int year1 = Integer.parseInt(date1.substring(0, 4));
        int year2 = Integer.parseInt(date2.substring(0, 4));
        int month1 = Integer.parseInt(date1.substring(5, 7));
        int month2 = Integer.parseInt(date2.substring(5, 7));
        int day1 = Integer.parseInt(date1.substring(8, 10));
        int day2 = Integer.parseInt(date2.substring(8, 10));
        
        int value = (year1 - year2) * 12 + (month1 - month2);
        if (day1 < day2) {value--;}
        
        return value;
    }
    
    /**
     * 获取两个日期对象相差天数
     *
     * @param date1str String yyyy-MM-dd
     * @param date2str String yyyy-MM-dd
     * @return int 日差值
     */
    public static int compareDay(String date1str, String date2str) {
        if (date1str == null || date2str == null) {return 0;}
        
        Date date1 = toDate(date1str, "00:00:00");
        Date date2 = toDate(date2str, "00:00:00");
        
        return compareDay(date1, date2);
    }
    
    /**
     * 获取两个日期对象相差天数
     *
     * @param date1 日期对象
     * @param date2 日期对象
     * @return int 日差值
     */
    public static int compareDay(Date date1, Date date2) {
        if (date1 == null || date2 == null) {return 0;}
        
        long time1 = date1.getTime();
        long time2 = date2.getTime();
        
        long margin = time1 - time2;
        
        /* 转化成天数 */
        return (int) Math.floor((double) margin / (1000 * 60 * 60 * 24));
    }
    
    /**
     * 获取两个日期对象相差的小时数
     *
     * @param date1str String yyyy-MM-dd hh:mm:ss
     * @param date2str String yyyy-MM-dd hh:mm:ss
     * @return int 相差小时数
     */
    public static int compareHour(String date1str, String date2str) {
        if (date1str == null || date2str == null) {return 0;}
        
        Date date1 = toDate(date1str);
        Date date2 = toDate(date2str);
        
        return compareHour(date1, date2);
    }
    
    /**
     * 获取两个日期对象相差的小时数
     *
     * @param date1 日期对象
     * @param date2 日期对象
     * @return int 相差小时数
     */
    public static int compareHour(Date date1, Date date2) {
        if (date1 == null || date2 == null) {return 0;}
        
        long time1 = date1.getTime();
        long time2 = date2.getTime();
        
        long margin = time1 - time2;
        
        return (int) Math.floor((double) margin / (1000 * 60 * 60));
    }
    
    /**
     * 获取两个日期对象相差的分钟数
     *
     * @param date1str String yyyy-MM-dd hh:mm:ss
     * @param date2str String yyyy-MM-dd hh:mm:ss
     * @return int 相差分钟数
     */
    public static int compareMinute(String date1str, String date2str) {
        if (date1str == null || date2str == null) {return 0;}
        
        Date date1 = toDate(date1str);
        Date date2 = toDate(date2str);
        
        return compareMinute(date1, date2);
    }
    
    /**
     * 获取两个日期对象相差的分钟数
     *
     * @param date1 日期对象
     * @param date2 日期对象
     * @return int 相差分钟数
     */
    public static int compareMinute(Date date1, Date date2) {
        if (date1 == null || date2 == null) {return 0;}
        
        long time1 = date1.getTime();
        long time2 = date2.getTime();
        
        long margin = time1 - time2;
        
        return (int) Math.floor((double) margin / (1000 * 60));
    }
    
    /**
     * 获取两个日期对象相差秒数
     *
     * @param date1str String yyyy-MM-dd hh:mm:ss
     * @param date2str String yyyy-MM-dd hh:mm:ss
     * @return int 相差秒数
     */
    public static int compareSecond(String date1str, String date2str) {
        if (date1str == null || date2str == null) {return 0;}
        
        Date date1 = toDate(date1str);
        Date date2 = toDate(date2str);
        
        return compareSecond(date1, date2);
    }
    
    /**
     * 获取两个日期对象相差秒数
     *
     * @param date1 日期对象
     * @param date2 日期对象
     * @return int 相差秒数
     */
    public static int compareSecond(Date date1, Date date2) {
        if (date1 == null || date2 == null) {return 0;}
        
        long time1 = date1.getTime();
        long time2 = date2.getTime();
        
        long margin = time1 - time2;
        
        long longValue = margin / (1000);
        
        return (int) longValue;
    }
    
    /**
     * 计算指定时间是当前时间的中文差值（1秒前，1分钟前，1小时前，1天前，1月前，1年前）
     *
     * @param date 日期格式
     * @return x秒前，x分钟前，x小时前，x天前，x月前，x年前
     */
    public static String compareDateTime(Date date) {
        long dateTimeMs = date.getTime();
        return compareDateTime(dateTimeMs);
    }
    
    /**
     * 计算指定时间是当前时间的中文差值（1秒前，1分钟前，1小时前，1天前，1月前，1年前）
     *
     * @param datetime 毫秒的时间（yyyy-MM-dd HH:mm:ss）格式
     * @return x秒前，x分钟前，x小时前，x天前，x月前，x年前
     */
    public static String compareDateTime(String datetime) {
        long dateTimeMs = toLong(datetime);
        return compareDateTime(dateTimeMs);
    }
    
    /**
     * 计算指定时间是当前时间的中文差值（1秒前，1分钟前，1小时前，1天前，1月前，1年前）
     *
     * @param dateTimeMs 毫秒的时间（1970-01-01 00：00：00）计算
     * @return x秒前，x分钟前，x小时前，x天前，x月前，x年前
     */
    public static String compareDateTime(long dateTimeMs) {
        long curTime = System.currentTimeMillis() / 1000;
        long cmpTime = dateTimeMs / 1000;
        
        if (curTime <= cmpTime) {return "1秒前";}
        
        long des = curTime - cmpTime;
        long year = des / _SECOND_IN_TIME_[0];
        if (year > 0) {return year + "年前";}
        
        long month = des / _SECOND_IN_TIME_[1];
        if (month > 0) {return month + "月前";}
        
        long day = des / _SECOND_IN_TIME_[2];
        if (day > 0) {return day + "天前";}
        
        long hour = des / _SECOND_IN_TIME_[3];
        if (hour > 0) {return hour + "小时前";}
        
        long minute = des / _SECOND_IN_TIME_[4];
        if (minute > 0) {return minute + "分钟前";}
        
        return des + "秒前";
    }
    
    /********************************************************/
    // 时间转换，String和Date之间转换
    /********************************************************/
    
    /**
     * 取得当前时间的HTTP要求格式
     *
     * @return format: Wed, 25 08 2011 12:11:35 GMT
     */
    public static String getDateTimeHttp() {
        Calendar calendar = Calendar.getInstance(new SimpleTimeZone(0, "GMT"));
        return getDateTimeHttp(calendar);
    }
    
    /**
     * 取得指定时间的HTTP要求格式
     *
     * @return format: Wed, 25 08 2011 12:11:35 GMT
     */
    public static String getDateTimeHttp(long millis) {
        Calendar calendar = Calendar.getInstance(new SimpleTimeZone(0, "GMT"));
        calendar.setTimeInMillis(millis);
        return getDateTimeHttp(calendar);
    }
    
    /**
     * 取得指定时间的HTTP要求格式
     *
     * @return format: Wed, 25 08 2011 12:11:35 GMT
     */
    public static String getDateTimeHttpNextHour() {
        Calendar calendar = Calendar.getInstance(new SimpleTimeZone(0, "GMT"));
        calendar.add(Calendar.HOUR_OF_DAY, 1);
        return getDateTimeHttp(calendar);
    }
    
    /**
     * 取得指定Calendar时间的HTTP要求格式
     *
     * @return format: Wed, 25 08 2011 12:11:35 GMT
     */
    public static String getDateTimeHttp(Calendar calendar) {
        StringBuilder buf = new StringBuilder();
        int week = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        int month = calendar.get(Calendar.MONTH);
        int year = calendar.get(Calendar.YEAR);
        
        int epoch = (int) ((calendar.getTimeInMillis() / 1000) % (60 * 60 * 24));
        int seconds = epoch % 60;
        epoch = epoch / 60;
        int minutes = epoch % 60;
        int hours = epoch / 60;
        
        buf.append(_WEEKS_[week]);
        buf.append(',');
        buf.append(' ');
        buf.append(StrUtils.prefixZero(day, 2));
        
        buf.append(' ');
        buf.append(_MONTHS_[month]);
        buf.append(' ');
        buf.append(StrUtils.prefixZero(year, 4));
        
        buf.append(' ');
        buf.append(StrUtils.prefixZero(hours, 2));
        buf.append(':');
        buf.append(StrUtils.prefixZero(minutes, 2));
        buf.append(':');
        buf.append(StrUtils.prefixZero(seconds, 2));
        buf.append(" GMT");
        
        return buf.toString();
    }
    
    /********************************************************/
    // 求星期取值
    /********************************************************/
    
    /**
     * 获取指定时间的星期数:星期日=0;星期一=1;星期二=2;星期三=3;星期四=4;星期五=5;星期六=6;
     *
     * @return 周数值
     */
    public static int getDateWeek(int date) {
        int year = date / 10000;
        int month = date / 100 % 100;
        int day = date % 100;
        
        // 采用日期第一秒，标准星期日=1，星期一=2，这里减1处理
        return toCalendar(year, month, day, 0, 0, 1).get(Calendar.DAY_OF_WEEK) - 1;
    }
    
    /**
     * 获取指定时间的星期数:星期日=7;星期一=1;星期二=2;星期三=3;星期四=4;星期五=5;星期六=6;
     *
     * @param date 日期，格式yyyyMMdd
     * @return 周数值，星期日=7，有利于算周末
     */
    public static int getDateWeek7(int date) {
        int week = getDateWeek(date);
        return (week == 0) ? 7 : week;
    }
    
    /**
     * 获取中文的星期几
     *
     * @param date 日期，格式yyyyMMdd
     * @return 星期X
     */
    public static String getDateWeekString(int date) {
        int week = getDateWeek(date);
        return _WEEKS_ZH_[week];
    }
    
    /**
     * 获取指定时间的星期数:星期日=0;星期一=1;星期二=2;星期三=3;星期四=4;星期五=5;星期六=6;
     *
     * @param year  年，格式yyyy
     * @param month 月，格式MM
     * @param day   日，格式dd
     * @return 周数值
     */
    public static int getDateWeek(int year, int month, int day) {
        // 采用日期第一秒，标准星期日=1，星期一=2，这里减1处理
        return toCalendar(year, month, day, 0, 0, 1).get(Calendar.DAY_OF_WEEK) - 1;
    }
    
    /**
     * 获取指定时间的星期数:星期日=7;星期一=1;星期二=2;星期三=3;星期四=4;星期五=5;星期六=6;
     *
     * @param year  年，格式yyyy
     * @param month 月，格式MM
     * @param day   日，格式dd
     * @return 周数值
     */
    public static int getDateWeek7(int year, int month, int day) {
        int week = getDateWeek(year, month, day);
        return (week == 0) ? 7 : week;
    }
    
    /**
     * 获取中文的星期几
     *
     * @param year  年，格式yyyy
     * @param month 月，格式MM
     * @param day   日，格式dd
     * @return 星期X
     */
    public static String getDateWeekString(int year, int month, int day) {
        int week = getDateWeek(year, month, day);
        return _WEEKS_ZH_[week];
    }
    
    /**
     * 获取指定时间的星期数:星期日=0;星期一=1;星期二=2;星期三=3;星期四=4;星期五=5;星期六=6;
     *
     * @param date 日期，格式yyyy-MM-dd
     * @return 周数值
     */
    public static int getDateWeek(String date) {
        return getDateTimeWeek(date + " 00:00:01");
    }
    
    /**
     * 获取指定时间的星期数:星期日=7;星期一=1;星期二=2;星期三=3;星期四=4;星期五=5;星期六=6;
     *
     * @param date 日期，格式yyyy-MM-dd
     * @return 周数值
     */
    public static int getDateWeek7(String date) {
        int week = getDateTimeWeek(date + " 00:00:01");
        return (week == 0) ? 7 : week;
    }
    
    /**
     * 获取 一年当中有多少 周
     *
     * @param year 指定年份
     * @return 一年中总共周数
     */
    public static int getYearWeeks(int year) {
        return 0;
    }
    
    /**
     * 获取指定日期在一年当中 的第几周
     *
     * @param date 指定日期
     * @return 周期值
     */
    public static int getWeekOfYear(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.WEEK_OF_YEAR);
    }
    
    /**
     * 获取中文的星期几
     *
     * @param date 时间格式yyyy-MM-dd
     * @return 星期X
     */
    public static String getDateWeekString(String date) {
        int week = getDateWeek(date);
        return _WEEKS_ZH_[week];
    }
    
    /**
     * 获取指定时间的星期数:星期日=0;星期一=1;星期二=2;星期三=3;星期四=4;星期五=5;星期六=6;
     *
     * @param datetime 时间格式yyyy-MM-dd HH:mm:ss
     * @return 周数值
     */
    public static int getDateTimeWeek(String datetime) {
        return toCalendar(datetime).get(Calendar.DAY_OF_WEEK) - 1;
    }
    
    /**
     * 获取指定时间的星期数:星期日=7;星期一=1;星期二=2;星期三=3;星期四=4;星期五=5;星期六=6;
     *
     * @param datetime 时间格式yyyy-MM-dd HH:mm:ss
     * @return 周数值
     */
    public static int getDateTimeWeek7(String datetime) {
        int week = getDateTimeWeek(datetime);
        return (week == 0) ? 7 : week;
    }
    
    /**
     * 获取中文的星期几
     *
     * @param datetime 时间格式yyyy-MM-dd HH:mm:ss
     * @return 星期X
     */
    public static String getDateTimeWeekString(String datetime) {
        int week = getDateTimeWeek(datetime);
        return _WEEKS_ZH_[week];
    }
    
    /*************************************************************/
    // 获取当前时间值，年、月、日期、小时、分钟、秒、星期
    /*************************************************************/
    
    /**
     * @return int[10]<br>
     * int[0] = year        4位数字<br>
     * int[1] = month       1-12<br>
     * int[2] = day         1-31<br>
     * int[3] = hour        0-23<br>
     * int[4] = min         0-59<br>
     * int[5] = sec         0-59<br>
     * int[6] = msec        0-999<br>
     * int[7] = week        1-7<br>
     * int[8] = yearMonth   201401<br>
     * int[9] = monthDays   28-31，当月天数
     */
    public static int[] getCurrent() {
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int min = calendar.get(Calendar.MINUTE);
        int sec = calendar.get(Calendar.SECOND);
        int msec = calendar.get(Calendar.MILLISECOND);
        int week = calendar.get(Calendar.DAY_OF_WEEK);
        week = week - 1;
        if (week == 0) week = 7;// 变成周一至周七分别为1-7
        
        int yearMonth = year * 100 + month;
        int monthDays = getMonthDays(year, month);// 月天数
        
        return new int[]{year, month, day, hour, min, sec, msec, week, yearMonth, monthDays};
    }
    
    /**
     * 获取当前日期，格式yyyyMMdd
     */
    public static int getCurrentDate() {
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        
        return year * 10000 + month * 100 + day;
    }
    
    /**
     * 获取当前年份, yyyy 格式
     */
    public static int getCurrentYear() {
        return Calendar.getInstance().get(Calendar.YEAR);
    }
    
    /**
     * 获取当前月份 1-12
     */
    public static int getCurrentMonth() {
        return Calendar.getInstance().get(Calendar.MONTH) + 1;
    }
    
    /**
     * 获取当前月天数
     */
    public static int getCurrentMonthDays() {
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;
        return getMonthDays(year, month);
    }
    
    /**
     * 获取当前月内的日期，1-31
     */
    public static int getCurrentDay() {
        return Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
    }
    
    /**
     * 获取当前年内的日期
     */
    public static int getCurrentYearDay() {
        return Calendar.getInstance().get(Calendar.DAY_OF_YEAR);
    }
    
    /**
     * 获取当前时
     */
    public static int getCurrentHour() {
        return Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
    }
    
    /**
     * 获取当前分
     */
    public static int getCurrentMinute() {
        return Calendar.getInstance().get(Calendar.MINUTE);
    }
    
    /**
     * 获取当前秒
     */
    public static int getCurrentSecond() {
        return Calendar.getInstance().get(Calendar.SECOND);
    }
    
    /**
     * 获取当前毫秒
     */
    public static int getCurrentMillis() {
        return Calendar.getInstance().get(Calendar.MILLISECOND);
    }
    
    /**
     * 获取当前时间的星期数:星期日=0;星期一=1;星期二=2;星期三=3;星期四=4;星期五=5;星期六=6;
     */
    public static int getCurrentWeek() {
        Calendar calendar = Calendar.getInstance();
        return calendar.get(Calendar.DAY_OF_WEEK) - 1;
    }
    
    /**
     * 获取当前时间的星期数:星期日=7;星期一=1;星期二=2;星期三=3;星期四=4;星期五=5;星期六=6;
     */
    public static int getCurrentWeek7() {
        Calendar calendar = Calendar.getInstance();
        int week = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        return week == 0 ? 7 : week;
    }
    
    /**
     * 获取当前的日期时间字符串MMddHHmmss
     */
    public static int getCurrentTime10() {
        Calendar calendar = Calendar.getInstance();
        int month = calendar.get(Calendar.MONTH) + 1;
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int min = calendar.get(Calendar.MINUTE);
        int sec = calendar.get(Calendar.SECOND);
        
        return month * 100000000 + day * 1000000 + hour * 10000 + min * 100 + sec;
    }
    
    /*************************************************************/
    // 获取当前时间格式，包括标准DT,D,T,17,14,12,8,7,6等常用格式
    /*************************************************************/
    
    /**
     * 取得当前的日期时间字符串
     *
     * @param format 格式,如yyyy-MM-dd HH:mm:ss
     * @return 取得当前的日期时间字符串
     */
    public static String getDateTimeString(String format) {
        return getFormatter(format).format(nowDate().toInstant());
    }
    
    /**
     * 取得当前的日期时间字符串yyyy-MM-dd HH:mm:ss
     *
     * @return String 取得当前的日期时间字符串yyyy-MM-dd HH:mm:ss
     */
    public static String getDateTimeString() {
        return DTF_YYYY_MM_DD_HH_MM_SS.format(nowDate().toInstant());
    }
    
    /**
     * 取得当前的日期时间字符串yyyyMMddHHmmssSSS
     *
     * @return String 取得当前的日期时间字符串yyyyMMddHHmmssSSS
     */
    public static String getDateTime17String() {
        return getFormatter("yyyyMMddHHmmssSSS").format(nowDate().toInstant());
    }
    
    /**
     * 取得当前的日期时间字符串yyyyMMddHHmmss
     *
     * @return String 取得当前的日期时间字符串yyyyMMddHHmmss
     */
    public static String getDateTime14String() {
        return DTF_YYYYMMDDHHMMSS.format(nowDate().toInstant());
    }
    
    /**
     * 取得当前的日期时间字符串yyMMddHHmmss
     *
     * @return String 取得当前的日期时间字符串yyMMddHHmmss
     */
    public static String getDateTime12String() {
        return getFormatter("yyMMddHHmmss").format(nowDate().toInstant());
    }
    
    /**
     * 取得当前的日期时间字符串yyMMddHHmmss
     *
     * @return String 取得当前的日期时间字符串yyMMddHHmmss
     */
    public static String getDateTime10String() {
        return getFormatter("yyMMddHHmm").format(nowDate().toInstant());
    }
    
    /**
     * 取得当前的日期时间字符串MMddHHmmss
     *
     * @return String 取得当前的日期时间字符串MMddHHmmss
     */
    public static String getDateTime10String2() {
        return DTF_MMDDHHMMSS.format(nowDate().toInstant());
    }
    
    /**
     * 取得当前的日期时间字符串yyyyMMdd
     *
     * @return String 取得当前的日期时间字符串
     */
    public static String getDateTime8String() {
        return getFormatter("yyyyMMdd").format(nowDate().toInstant());
    }
    
    /**
     * 取得当前的日期时间字符串MMddHHmm
     *
     * @return String 取得当前的日期时间字符串
     */
    public static String getDateTime8String2() {
        return getFormatter(MMDDHHMM).format(nowDate().toInstant());
    }
    
    /**
     * 取得当前的日期时间字符串yyyy-MM
     *
     * @return String 取得当前的日期时间字符串
     */
    public static String getDateTime7String() {
        return getFormatter("yyyy-MM").format(nowDate().toInstant());
    }
    
    /**
     * 取得当前的日期时间字符串yyyyMM
     *
     * @return String 取得当前的日期时间字符串
     */
    public static String getDateTime6String() {
        return getFormatter("yyyyMM").format(nowDate().toInstant());
    }
    
    /**
     * 取得当前的日期时间字符串yyyyMMdd
     *
     * @return int yyyyMMdd 的 int值
     */
    public static int getDateInt() {
        return Integer.parseInt(getFormatter("yyyyMMdd").format(nowDate().toInstant()));
    }
    
    /**
     * 取得当前的日期时间字符串yyyy-MM-dd
     *
     * @return String 取得当前的日期时间字符串
     */
    public static String getDateString() {
        return DTF_YYYY_MM_DD.format(nowDate().toInstant());
    }
    
    /**
     * 取得当前的日期时间字符串HH:mm:ss
     *
     * @return String 取得当前的日期时间字符串
     */
    public static String getTimeString() {
        return DTF_HH_MM_SS.format(nowDate().toInstant());
    }
    
    /**
     * 取得当前的日期时间字符串yyyy-MM-dd HH:mm:ss,SSS
     *
     * @return String 取得当前的日期时间字符串YYYY-MM-DD HH:mm:ss,SSS
     */
    public static String getDateTimeSSSString() {
        return DTF_YYYY_MM_DD_HH_MM_SS_SSS.format(nowDate().toInstant());
    }
    
    /**
     * 取得当前的日期时间字符串YYYY/MM/DD HH:mm:ss (移动)
     *
     * @return String 取得当前的日期时间字符串YYYY/MM/DD HH:mm:ss
     */
    public static String getDateTimeStringSlash() {
        return getFormatter("yyyy/MM/dd HH:mm:ss").format(nowDate().toInstant());
    }
    
    /**
     * 取得当前的日期时间字符串YYYY/MM/DD HH:mm:ss (移动)
     *
     * @return String 取得当前的日期时间字符串YYYY/MM/DD HH:mm:ss
     */
    public static String getDateStringSlash() {
        return getFormatter("yyyy/MM/dd").format(nowDate().toInstant());
    }
    
    /*************************************************************/
    // 获取当月月初和月末日期，上月下月月初月末，如2013-12-01,2013-12-31
    /*************************************************************/
    
    /**
     * 取得当月第一天
     */
    public static String getFirstMonthDay() {
        return getDateTime7String() + "-01";
    }
    
    /**
     * 获到当前月最后一天yyyy-MM-dd
     */
    public static String getLastMonthDay() {
        String curYearMonth = getDateTime6String();
        return getLastMonthDay(curYearMonth);
    }
    
    /**
     * 获取上一个月第一天 yyyy-MM-dd
     */
    public static String getPreviousMonthFirstDay() {
        String curYearMonth = getDateTime6String();
        String yearMonth = getPreviousYearMonth(curYearMonth);
        return yearMonth.substring(0, 4) + "-" + yearMonth.substring(4) + "-01";
    }
    
    /**
     * 获到上一月最后一天yyyy-MM-dd
     */
    public static String getPreviousMonthLastDay() {
        String curYearMonth = getDateTime6String();
        String yearMonth = getPreviousYearMonth(curYearMonth);
        return getLastMonthDay(yearMonth);
    }
    
    /**
     * 获取下一个月第一天 yyyy-MM-dd
     */
    public static String getNextMonthFirstDay() {
        String curYearMonth = getDateTime6String();
        String yearMonth = getNextMonth(curYearMonth);
        return yearMonth.substring(0, 4) + "-" + yearMonth.substring(4) + "-01";
    }
    
    /**
     * 获到下一月最后一天yyyy-MM-dd
     */
    public static String getNextMonthLastDay() {
        String curYearMonth = getDateTime6String();
        String yearMonth = getNextMonth(curYearMonth);
        return getLastMonthDay(yearMonth);
    }
    
    /*************************************************************/
    // 获取向前推进的时间格式，包括推月、日、时、秒对应的日期和时间格式
    /*************************************************************/
    
    /**
     * 获取前一天对应的当前时间,采用标准格式yyyy-MM-dd
     *
     * @return String
     */
    public static String getPreviousDateString() {
        return getPreviousDateTimeString(YYYY_MM_DD);
    }
    
    /**
     * 获取前一天对应的当前时间,采用短信格式yyyy/MM/dd
     *
     * @return String
     */
    public static String getPreviousDateStringSlash() {
        return getPreviousDateTimeString("yyyy/MM/dd");
    }
    
    /**
     * 获取前一天对应的当前时间
     *
     * @param format 格式化如 yyyy-MM-dd HH:mm:ss
     * @return String
     */
    public static String getPreviousDateTimeString(String format) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        
        return toDateTimeString(calendar, format);
    }
    
    /**
     * 获取前一天对应的当前时间,采用标准格式yyyy-MM-dd HH:mm:ss
     *
     * @return String
     */
    public static String getPreviousDateTimeString() {
        return getPreviousDateTimeString(YYYY_MM_DD_HH_MM_SS);
    }
    
    /**
     * 获取前一天对应的当前时间,采用短信格式yyyy/MM/dd HH:mm:ss
     *
     * @return String
     */
    public static String getPreviousDateTimeStringSlash() {
        return getPreviousDateTimeString("yyyy/MM/dd HH:mm:ss");
    }
    
    //////////////////////////////////////////////////
    // getPreviousDateString()
    /////////////////////////////////////////////////
    
    /**
     * 获取前几天对应的当前时间
     *
     * @param days 相差天数
     * @return String yyyy-MM-dd
     */
    public static String getPreviousDateString(int days) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, -days);
        
        return toDateString(calendar);
    }
    
    /**
     * 获取前几年对应的当前时间
     *
     * @param years 相差年数
     * @return String yyyy-MM-dd
     */
    public static String getPreviousDateStringByYear(int years) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.YEAR, -years);
        
        return toDateString(calendar);
    }
    
    /**
     * 获取前几月对应的当前时间
     *
     * @param months 相差月数
     * @return String yyyy-MM-dd
     */
    public static String getPreviousDateStringByMonth(int months) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, -months);
        
        return toDateString(calendar);
    }
    
    /**
     * 获取前几小时对应的当前时间
     *
     * @param hours 相差小时数
     * @return String yyyy-MM-dd
     */
    public static String getPreviousDateStringByHour(int hours) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.HOUR_OF_DAY, -hours);
        
        return toDateString(calendar);
    }
    
    /**
     * 获取前几秒对应的当前时间
     *
     * @param seconds 秒数
     * @return String yyyy-MM-dd
     */
    public static String getPreviousDateStringBySecond(int seconds) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, -seconds);
        
        return toDateString(calendar);
    }
    
    //////////////////////////////////////////////////
    // getPreviousDateTimeString()
    /////////////////////////////////////////////////
    
    /**
     * 获取前几天对应的当前时间
     *
     * @param days 相差天数
     * @return String yyyy-MM-dd HH:mm:ss
     */
    public static String getPreviousDateTimeString(int days) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, -days);
        
        return toDateTimeString(calendar);
    }
    
    /**
     * 获取前几年对应的当前时间
     *
     * @param years 相差年数
     * @return String yyyy-MM-dd HH:mm:ss
     */
    public static String getPreviousDateTimeStringByYear(int years) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.YEAR, -years);
        
        return toDateTimeString(calendar);
    }
    
    /**
     * 获取前几月对应的当前时间
     *
     * @param months 相差月数
     * @return String yyyy-MM-dd HH:mm:ss
     */
    public static String getPreviousDateTimeStringByMonth(int months) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, -months);
        
        return toDateTimeString(calendar);
    }
    
    
    /**
     * 获取前几小时对应的当前时间
     *
     * @param hours 相差小时数
     * @return String yyyy-MM-dd HH:mm:ss
     */
    public static String getPreviousDateTimeStringByHour(int hours) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.HOUR_OF_DAY, -hours);
        
        return toDateTimeString(calendar);
    }
    
    /**
     * 获取前几秒对应的当前时间
     *
     * @param seconds 秒数
     * @return String yyyy-MM-dd HH:mm:ss
     */
    public static String getPreviousDateTimeStringBySecond(int seconds) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, -seconds);
        
        return toDateTimeString(calendar);
    }
    
    /**
     * 获取指定时间的前一天日期
     *
     * @param date 指定日期
     * @return yyyy-MM-dd
     */
    public static String getPreviousDateString(String date) {
        return getPreviousDateString(date, 1);
    }
    
    /**
     * 获取指定时间前几天的时间
     *
     * @param date 指定日期 yyyy-MM-dd 或者 yyyy-MM-dd HH:mm:ss
     * @param days 相差天数
     * @return String yyyy-MM-dd
     */
    public static String getPreviousDateString(String date, int days) {
        Calendar calendar = toCalendar(date);
        calendar.add(Calendar.DAY_OF_MONTH, -days);
        
        return toDateString(calendar);
    }
    
    /**
     * 获取指定时间前几年的时间
     *
     * @param datetime 指定时间
     * @param years    相差年数
     * @return String yyyy-MM-dd
     */
    public static String getPreviousDateStringByYear(String datetime, int years) {
        Calendar calendar = toCalendar(datetime);
        calendar.add(Calendar.YEAR, -years);
        
        return toDateString(calendar);
    }
    
    /**
     * 获取指定时间前几月的时间
     *
     * @param datetime 指定时间
     * @param months   相差月数
     * @return String yyyy-MM-dd
     */
    public static String getPreviousDateStringByMonth(String datetime, int months) {
        Calendar calendar = toCalendar(datetime);
        calendar.add(Calendar.MONTH, -months);
        
        return toDateString(calendar);
    }
    
    /**
     * 获取指定时间前几小时的时间
     *
     * @param datetime 指定时间
     * @param hours    相差小时数
     * @return String yyyy-MM-dd
     */
    public static String getPreviousDateStringByHour(String datetime, int hours) {
        Calendar calendar = toCalendar(datetime);
        calendar.add(Calendar.HOUR_OF_DAY, -hours);
        
        return toDateString(calendar);
    }
    
    /**
     * 获取指定时间前几秒的时间
     *
     * @param datetime 指定时间
     * @param seconds  相差秒数
     * @return String yyyy-MM-dd
     */
    public static String getPreviousDateStringBySecond(String datetime, int seconds) {
        Calendar calendar = toCalendar(datetime);
        calendar.add(Calendar.SECOND, -seconds);
        
        return toDateString(calendar);
    }
    
    //////////////////////////////////////////////////
    // getPreviousDateTimeString
    /////////////////////////////////////////////////
    
    /**
     * 获取指定时间前几天的时间
     *
     * @param datetime 指定时间
     * @param days     相差天数
     * @return String yyyy-MM-dd HH:mm:ss
     */
    public static String getPreviousDateTimeString(String datetime, int days) {
        Calendar calendar = toCalendar(datetime);
        calendar.add(Calendar.DAY_OF_MONTH, -days);
        
        return toDateTimeString(calendar);
    }
    
    /**
     * 获取指定时间前几月的时间
     *
     * @param datetime 指定时间
     * @param years    相差年数
     * @return String yyyy-MM-dd HH:mm:ss
     */
    public static String getPreviousDateTimeStringByYear(String datetime, int years) {
        Calendar calendar = toCalendar(datetime);
        calendar.add(Calendar.YEAR, -years);
        
        return toDateTimeString(calendar);
    }
    
    /**
     * 获取指定时间前几月的时间
     *
     * @param datetime 指定时间
     * @param months   相差月数
     * @return String yyyy-MM-dd HH:mm:ss
     */
    public static String getPreviousDateTimeStringByMonth(String datetime, int months) {
        Calendar calendar = toCalendar(datetime);
        calendar.add(Calendar.MONTH, -months);
        
        return toDateTimeString(calendar);
    }
    
    /**
     * 获取指定时间前几小时的时间
     *
     * @param datetime 指定时间
     * @param hours    相差小时数
     * @return String yyyy-MM-dd HH:mm:ss
     */
    public static String getPreviousDateTimeStringByHour(String datetime, int hours) {
        Calendar calendar = toCalendar(datetime);
        calendar.add(Calendar.HOUR_OF_DAY, -hours);
        
        return toDateTimeString(calendar);
    }
    
    /**
     * 获取指定时间前几秒的时间
     *
     * @param datetime 指定时间
     * @param second   秒数
     * @return String yyyy-MM-dd HH:mm:ss
     */
    public static String getPreviousDateTimeStringBySecond(String datetime, int second) {
        Calendar calendar = toCalendar(datetime);
        calendar.add(Calendar.SECOND, -second);
        
        return toDateTimeString(calendar);
    }
    
    /*************************************************************/
    // 获取向后推进的时间格式，包括推月、日、时、秒对应的日期和时间格式
    /*************************************************************/
    
    /**
     * 获取后一天对应的当前时间,采用标准格式yyyy-MM-dd
     *
     * @return String
     */
    public static String getNextDateString() {
        return getNextDateTimeString(YYYY_MM_DD);
    }
    
    /**
     * 获取后一天对应的当前时间,采用标准格式yyyy-MM-dd HH:mm:ss
     *
     * @return String
     */
    public static String getNextDateTimeString() {
        return getNextDateTimeString(YYYY_MM_DD_HH_MM_SS);
    }
    
    /**
     * 获取后一天对应的当前时间
     *
     * @param format 格式化如 yyyy-MM-dd HH:mm:ss
     * @return String
     */
    public static String getNextDateTimeString(String format) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, 1);
        
        return toDateTimeString(calendar, format);
    }
    
    /**
     * 获取指定日期的后几天日期
     *
     * @param days 天数
     * @return Date 几天后的当前日期
     */
    public static Date getNextDate(int days) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, days);
        
        return calendar.getTime();
    }
    
    /**
     * 获取后几年对应的当前日期
     *
     * @param years 年数
     * @return 几年后的当前日期格式
     */
    public static Date getNextDateByYeah(int years) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.YEAR, years);
        
        return calendar.getTime();
    }
    
    /**
     * 获取指定日期的后几月日期
     *
     * @param months 月数
     * @return Date 几月后的当前日期
     */
    public static Date getNextDateByMonth(int months) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, months);
        
        return calendar.getTime();
    }
    
    /**
     * 获取指定日期的后几小时日期
     *
     * @param hours 小时数
     * @return Date 几小时后的当前日期
     */
    public static Date getNextDateByHour(int hours) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.HOUR_OF_DAY, hours);
        
        return calendar.getTime();
    }
    
    /**
     * 获取指定日期的后几秒日期
     *
     * @param seconds 秒数
     * @return Date 几小时后的当前日期
     */
    public static Date getNextDateBySecond(int seconds) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, seconds);
        
        return calendar.getTime();
    }
    
    /**
     * 获取后几天对应的当前日期
     *
     * @param days 日期数
     * @return String 后几天对应的当前日期
     */
    public static String getNextDateString(int days) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, days);
        
        return toDateString(calendar);
    }
    
    /**
     * 获取后几年对应的当天日期
     *
     * @param years 年数
     * @return String 后几年的日期yyyy-MM-dd
     */
    public static String getNextDateStringByYeah(int years) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.YEAR, years);
        
        return toDateString(calendar);
    }
    
    /**
     * 获取后几月对应的当前日期
     *
     * @param months 月数
     * @return String 几月后的当前日期
     */
    public static String getNextDateStringByMonth(int months) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, months);
        
        return toDateString(calendar);
    }
    
    /**
     * 获取后几小时对应的当前日期
     *
     * @param hours 格式化如 yyyy-MM-dd
     * @return String 几小时后对应的当前日期
     */
    public static String getNextDateStringByHour(int hours) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.HOUR_OF_DAY, hours);
        
        return toDateString(calendar);
    }
    
    /**
     * 获取后几秒对应的当前日期
     *
     * @param seconds 秒数
     * @return String 几秒后对应的当前日期
     */
    public static String getNextDateStringBySecond(int seconds) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, seconds);
        
        return toDateString(calendar);
    }
    
    /**
     * 获取指定时间的后一天日期
     *
     * @param date 指定日期
     * @return yyyy-MM-dd
     */
    public static String getNextDateString(String date) {
        return getNextDateString(date, 1);
    }
    
    /**
     * 获取指定日期的后几天日期
     *
     * @param date 指定日期
     * @param days 指定天数
     * @return yyyy-MM-dd
     */
    public static String getNextDateString(String date, int days) {
        Calendar calendar = toCalendar(date + " 00:00:00");
        calendar.add(Calendar.DAY_OF_MONTH, days);
        return toDateString(calendar);
    }
    
    /**
     * 获取指定日期的后几年日期
     *
     * @param date  指定日期
     * @param years 指定年数
     * @return yyyy-MM-dd
     */
    public static String getNextDateStringByYear(String date, int years) {
        Calendar calendar = toCalendar(date + " 00:00:00");
        calendar.add(Calendar.YEAR, years);
        return toDateString(calendar);
    }
    
    /**
     * 获取指定日期的后几月日期
     *
     * @param date   指定日期
     * @param months 指定月数
     * @return yyyy-MM-dd
     */
    public static String getNextDateStringByMonth(String date, int months) {
        Calendar calendar = toCalendar(date + " 00:00:00");
        calendar.add(Calendar.MONTH, months);
        return toDateString(calendar);
    }
    
    /**
     * 获取指定日期的后几小时
     *
     * @param date  指定日期
     * @param hours 指定小时数
     * @return yyyy-MM-dd
     */
    public static String getNextDateStringByHour(String date, int hours) {
        Calendar calendar = toCalendar(date + " 00:00:00");
        calendar.add(Calendar.HOUR_OF_DAY, hours);
        return toDateString(calendar);
    }
    
    /**
     * 获取指定日期的后几秒
     *
     * @param date    指定日期
     * @param seconds 指定秒数
     * @return yyyy-MM-dd
     */
    public static String getNextDateStringBySecond(String date, int seconds) {
        Calendar calendar = toCalendar(date + " 00:00:00");
        calendar.add(Calendar.SECOND, seconds);
        return toDateString(calendar);
    }
    
    /**
     * 获取后几天对应的当前时间
     *
     * @param days 天数
     * @return String 几天后对应的当前时间
     */
    public static String getNextDateTimeString(int days) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, days);
        
        return toDateTimeString(calendar);
    }
    
    /**
     * 获取后几年对应的当前时间
     *
     * @param years 年数
     * @return String 几年后对应的当前时间
     */
    public static String getNextDateTimeStringByYear(int years) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.YEAR, years);
        
        return toDateTimeString(calendar);
    }
    
    /**
     * 获取后几月对应的当前时间
     *
     * @param months 月数
     * @return String 几月后对应的当前时间
     */
    public static String getNextDateTimeStringByMonth(int months) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, months);
        
        return toDateTimeString(calendar);
    }
    
    /**
     * 获取后几小时对应的当前时间
     *
     * @param hours 小时数
     * @return String 几小时后对应的当前时间
     */
    public static String getNextDateTimeStringByHour(int hours) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.HOUR_OF_DAY, hours);
        
        return toDateTimeString(calendar);
    }
    
    /**
     * 获取后几秒对应的当前时间
     *
     * @param seconds 秒数
     * @return String 几秒后对应的当前时间
     */
    public static String getNextDateTimeStringBySecond(int seconds) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, seconds);
        
        return toDateTimeString(calendar);
    }
    
    /**
     * 获取指定时间后几日的时间
     *
     * @param datetime 指定时间
     * @param days     相差日数
     * @return String yyyy-MM-dd HH:mm:ss
     */
    public static String getNextDateTimeString(String datetime, int days) {
        Calendar calendar = toCalendar(datetime);
        calendar.add(Calendar.DAY_OF_MONTH, days);
        
        return toDateTimeString(calendar);
    }
    
    /**
     * 获取指定时间后几年的时间
     *
     * @param datetime 指定时间
     * @param years    相差年数
     * @return String yyyy-MM-dd HH:mm:ss
     */
    public static String getNextDateTimeStringByYear(String datetime, int years) {
        Calendar calendar = toCalendar(datetime);
        calendar.add(Calendar.YEAR, years);
        
        return toDateTimeString(calendar);
    }
    
    /**
     * 获取指定时间后几月的时间
     *
     * @param datetime 指定时间
     * @param months   相差月数
     * @return String yyyy-MM-dd HH:mm:ss
     */
    public static String getNextDateTimeStringByMonth(String datetime, int months) {
        Calendar calendar = toCalendar(datetime);
        calendar.add(Calendar.MONTH, months);
        
        return toDateTimeString(calendar);
    }
    
    /**
     * 获取指定时间后几小时对应的当前时间
     *
     * @param datetime 格式 yyyy-MM-dd HH:mm:ss
     * @param hours    小时数
     * @return yyyy-MM-dd HH:mm:ss
     */
    public static String getNextDateTimeStringByHour(String datetime, int hours) {
        Calendar calendar = toCalendar(datetime);
        calendar.add(Calendar.HOUR_OF_DAY, hours);
        
        return toDateTimeString(calendar);
    }
    
    /**
     * 获取指定时间后几秒对应的当前时间
     *
     * @param datetime 格式 yyyy-MM-dd HH:mm:ss
     * @param seconds  秒数
     * @return yyyy-MM-dd HH:mm:ss
     */
    public static String getNextDateTimeStringBySecond(String datetime, int seconds) {
        Calendar calendar = toCalendar(datetime);
        calendar.add(Calendar.SECOND, seconds);
        
        return toDateTimeString(calendar);
    }
    
    /*******************************************************************************/
    // 时区
    /*******************************************************************************/
    
    /**
     * 获取当前时区
     */
    public static TimeZone getTimeZone() {
        return Calendar.getInstance().getTimeZone();
    }
    
    /**
     * 获取当前时区小时数
     */
    public static int getTimeZoneHour() {
        return Calendar.getInstance().getTimeZone().getRawOffset() / (60 * 60 * 1000);
    }
    
    /**
     * 获取当前时区分钟数
     */
    public static int getTimeZoneMinute() {
        return Calendar.getInstance().getTimeZone().getRawOffset() / (60 * 1000);
    }
    
    /**
     * 获取当前时区秒数
     */
    public static int getTimeZoneSecond() {
        return Calendar.getInstance().getTimeZone().getRawOffset() / 1000;
    }
    
    
}
